Skip to content

[Toolkit][Shadcn] Add code-block recipe - #4100

Merged
Kocal merged 1 commit into
symfony:3.xfrom
ker0x:feat/toolkit-shadcn-code-block
Oct 19, 2026
Merged

Kocal merged 1 commit into
symfony:3.xfrom
ker0x:feat/toolkit-shadcn-code-block

Conversation

@ker0x

@ker0x ker0x commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor
Q A
Bug fix? no
New feature? yes
Deprecations? no
Documentation? yes
Issues Part of #3233
License MIT

The Shadcn kit had no code-block recipe, the component Shadcn uses to display code, terminal output, logs and diffs.

This adds it, ported from the Nova style: CodeBlock (with a destructive variant and an sm size), CodeBlock:Header, CodeBlock:Title, CodeBlock:Actions, CodeBlock:CopyButton, CodeBlock:Content, CodeBlock:Line (added, removed and highlighted variants) and CodeBlock:Footer. CodeBlock:Content takes a code string or a list of CodeBlock:Line, and supports wrap, lineNumbers and startLine. Line numbers and diff markers are generated content, left out of a copied selection, and blank lines survive the copy. The content is always dir="ltr", and the header follows the page direction.

A code-block Stimulus controller replaces the React state of upstream: copy (check icon, "Copied" label and live region for 2 seconds), download, toggleWrap (syncs aria-pressed) and toggleExpanded (toggles data-expanded on the content the button controls, for Show More). The edges fade with the scroll-fade-* utilities of the shadcn package the kit already depends on.

Choices that differ from upstream:

  • The copy text is read from a data-code-block-text attribute rather than a Stimulus param, since Stimulus parses params as JSON and would turn a JSON snippet into an object.
  • scrollbar-thin only exists since Tailwind 4.3. The Toolkit builds with Tailwind 4.2. The recipe uses [scrollbar-width:thin] instead, which works in both versions.
  • Syntax highlighting is not ported: upstream does it with Shiki in a React hook. The README has a Syntax Highlighting section instead, which shows how to pass lines highlighted by the application to CodeBlock:Line. It lists Phiki, tempest/highlight and Shiki as options. The Languages, Terminal Output, Streaming and Markdown sections are left out. Examples that only used highlighting for looks show plain text.
  • The Typeset example is left out: it relies on the typeset stylesheet of the Shadcn docs site, shipped neither by the kit nor by the shadcn package.

The README carries the demo and every other example of the upstream documentation: Basic, Header, Actions, Floating Actions, Line Numbers, Start Line, Wrap, Highlighted Lines, Diff, Height, Show More, Max Height, Size, Destructive, Trace, Tabs, Message and RTL, plus an Accessibility section. A lucide:wrap-text icon fixture is added.

The trace README used <pre> elements styled like a code block, since the kit had none. They are replaced with CodeBlock, as upstream does.

Checks run:

  • ComponentsRenderingTest: snapshots of the 19 examples, and the full Toolkit PHPUnit suite (1408 tests) passes.
  • Playwright: 50 tests for the recipe (screenshots in light and dark mode, plus specs for copying, the reset after 2 seconds, a selection without line numbers, the wrap toggle, the download, Show More, the higher cap and the floating actions on focus), and the 40 tests of trace pass.
  • ux-toolkit-kit-lint --fail-on-warning, oxfmt and oxlint are clean.

@ker0x
ker0x requested a review from Kocal as a code owner October 15, 2026 07:34
@carsonbot carsonbot added Documentation Improvements or additions to documentation Feature New Feature Toolkit Status: Needs Review Needs to be reviewed labels Oct 15, 2026
| Q              | A
| -------------- | ---
| Bug fix?       | no
| New feature?   | yes
| Deprecations?  | no
| Documentation? | yes
| Issues         | Part of symfony#3233
| License        | MIT

The Shadcn kit had no `code-block` recipe, the component Shadcn uses to display code, terminal output, logs and diffs.

This adds it, ported from the Nova style: `CodeBlock` (with a `destructive` variant and an `sm` size), `CodeBlock:Header`, `CodeBlock:Title`, `CodeBlock:Actions`, `CodeBlock:CopyButton`, `CodeBlock:Content`, `CodeBlock:Line` (`added`, `removed` and `highlighted` variants) and `CodeBlock:Footer`. `CodeBlock:Content` takes a `code` string or a list of `CodeBlock:Line`, and supports `wrap`, `lineNumbers` and `startLine`. Line numbers and diff markers are generated content, left out of a copied selection, and blank lines survive the copy. The content is always `dir="ltr"`, and the header follows the page direction.

A `code-block` Stimulus controller replaces the React state of upstream: `copy` (check icon, "Copied" label and live region for 2 seconds), `download`, `toggleWrap` (syncs `aria-pressed`) and `toggleExpanded` (toggles `data-expanded` on the content the button controls, for Show More). The edges fade with the `scroll-fade-*` utilities of the `shadcn` package the kit already depends on.

Choices that differ from upstream:

- The copy text is read from a `data-code-block-text` attribute rather than a Stimulus param, since Stimulus parses params as JSON and would turn a JSON snippet into an object.
- `scrollbar-thin` only exists since Tailwind 4.3. The Toolkit builds with Tailwind 4.2. The recipe uses `[scrollbar-width:thin]` instead, which works in both versions.
- Syntax highlighting is not ported: upstream does it with Shiki in a React hook. The README has a Syntax Highlighting section instead, which shows how to pass lines highlighted by the application to `CodeBlock:Line`. It lists Phiki, tempest/highlight and Shiki as options. The Languages, Terminal Output, Streaming and Markdown sections are left out. Examples that only used highlighting for looks show plain text.
- The Typeset example is left out: it relies on the `typeset` stylesheet of the Shadcn docs site, shipped neither by the kit nor by the `shadcn` package.

The README carries the demo and every other example of the upstream documentation: Basic, Header, Actions, Floating Actions, Line Numbers, Start Line, Wrap, Highlighted Lines, Diff, Height, Show More, Max Height, Size, Destructive, Trace, Tabs, Message and RTL, plus an Accessibility section. A `lucide:wrap-text` icon fixture is added.

The `trace` README used `<pre>` elements styled like a code block, since the kit had none. They are replaced with `CodeBlock`, as upstream does.

Checks run:

- `ComponentsRenderingTest`: snapshots of the 19 examples, and the full Toolkit PHPUnit suite (1408 tests) passes.
- Playwright: 50 tests for the recipe (screenshots in light and dark mode, plus specs for copying, the reset after 2 seconds, a selection without line numbers, the wrap toggle, the download, Show More, the higher cap and the floating actions on focus), and the 40 tests of `trace` pass.
- `ux-toolkit-kit-lint --fail-on-warning`, `oxfmt` and `oxlint` are clean.
@Kocal
Kocal force-pushed the feat/toolkit-shadcn-code-block branch from e8c54a2 to a966d00 Compare October 19, 2026 09:29
@carsonbot carsonbot added Status: Reviewed Has been reviewed by a maintainer and removed Status: Needs Review Needs to be reviewed labels Oct 19, 2026
@Kocal

Kocal commented Oct 19, 2026

Copy link
Copy Markdown
Member

Thank you @ker0x.

@Kocal
Kocal merged commit 8e4daf2 into symfony:3.x Oct 19, 2026
48 checks passed
@Kocal Kocal mentioned this pull request Oct 19, 2026
95 of 100 tasks
@ker0x
ker0x deleted the feat/toolkit-shadcn-code-block branch October 19, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Documentation Improvements or additions to documentation Feature New Feature Status: Reviewed Has been reviewed by a maintainer Toolkit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants